/******************************************************************************
 * Copyright (C) 2015  671643387@qq.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *****************************************************************************/

#include "Ucop/Base/Console.h"
#include <cstdarg>
#include <cstdio>
/* Default lock console for output */
#ifndef _UCOP_UNLOCK_CONSOLE
#include "Ucop/System/Mutex.h"
static Ucop::System::Mutex _sConsoleLock;
#endif /* _UCOP_UNLOCK_CONSOLE */


namespace Ucop {
namespace Console {

#ifndef _UCOP_UNLOCK_CONSOLE
    GuardImpl::GuardImpl(void)
    {
        _sConsoleLock.Lock();
    }
    GuardImpl::~GuardImpl(void)
    {
        _sConsoleLock.Unlock();
    }
#else
    GuardImpl::GuardImpl(void)
    {
    }
    GuardImpl::~GuardImpl(void)
    {
    }
#endif

    void SetColor(int _Type, int _Color)
    {
        HANDLE _Console = NULL;
        WORD _Wcolor = (WORD)_Color;
        if (_Type == STDOUT) {
            _Console = GetStdHandle(STD_OUTPUT_HANDLE);
        }
        else {
            _Console = GetStdHandle(STD_ERROR_HANDLE);
        }
        if (_Console == NULL
            || _Console == INVALID_HANDLE_VALUE) {
            return;
        }
        SetConsoleTextAttribute(_Console, _Wcolor);
    }

    void info(const char *_Format, ...)
    {
        UCOP_LOCK_CONSOLE;

        std::va_list _Args;
        va_start(_Args, _Format);
        vfprintf_s(stdout, _Format, _Args);
        va_end(_Args);
        fflush(stdout);

    }

    void warning(const char *_Format, ...)
    {
        UCOP_LOCK_CONSOLE;

        SetColor(STDOUT, COLOR_FOREGUARD_YELLOW | COLOR_FOREGUARD_INTENSITY);
        std::va_list _Args;
        va_start(_Args, _Format);
        vfprintf_s(stdout, _Format, _Args);
        va_end(_Args);
        fflush(stdout);
        SetColor(STDOUT, COLOR_FOREGUARD_WHITE);
    }

    void error(const char *_Format, ...)
    {
        UCOP_LOCK_CONSOLE;

        SetColor(STDERR, COLOR_FOREGUARD_RED | COLOR_FOREGUARD_INTENSITY);
        std::va_list _Args;
        va_start(_Args, _Format);
        vfprintf_s(stderr, _Format, _Args);
        va_end(_Args);
        fflush(stderr);
        SetColor(STDERR, COLOR_FOREGUARD_WHITE);
    }
}}